
package com.bosssoft.boss_exam_db.service.base.impl;

import com.bosssoft.boss_exam_db.service.base.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.common.Mapper;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

/**
 * 通用Service
 * @param <T>
 */
@Slf4j
public abstract class BaseServiceImpl<T> implements BaseService<T> {

    @Autowired
    protected Mapper<T> mapper;

    
    public Mapper<T> getMapper() {
        return mapper;
    }

    /***
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/3/14
     * @Description 根据ID查询实体记录 
     * @Param [key] 实体ID字段
     * @Return T 实体记录
     * @Exception 反射相关的异常，如访问未找到，非法访问等异常     
     * @since JDK 1.8       
     **/
    @Override
    public T selectByKey(Object key) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //说明：根据主键字段进行查询，方法参数必须包含完整的主键属性，查询条件使用等号
        Method method = null;
        Boolean deletedFlag=false;
        T entity = mapper.selectByPrimaryKey(key);
        method = entity.getClass().getMethod("getDeleted",null);
        deletedFlag = (Boolean)method.invoke(entity, null);
        return deletedFlag?null:entity;
    }

    /***
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/3/14
     * @Description 保存实体对象
     * @Param [entity] 需保存的实体对象
     * @Return int 影响行数
     * @Exception //无     
     * @since JDK 1.8       
     **/
    @Override
    public int save(T entity) {
        //说明：保存一个实体，null的属性也会保存，不会使用数据库默认值
        return mapper.insert(entity);
    }

    /***
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/3/14
     * @Description 保存实体，属性不为null的值
     * @Param [entity] 需保存的实体对象
     * @Return int 影响函数
     * @Exception 无     
     * @since JDK 1.8       
     **/
    @Override
    public int saveNotNull(T entity) {
        //说明：保存一个实体，属性不为null的值
        return mapper.insertSelective(entity);
    }

    /***
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/3/14
     * @Description  删除，物理删除，在数据库中擦除数据
     * @Param [key] 需删除实体的ID标识
     * @Return int 影响行数
     * @Exception //无   
     * @since JDK 1.8       
     **/
    @Override
    public int delete(Object key) {
        //说明：根据主键字段进行删除，方法参数必须包含完整的主键属性
        return mapper.deleteByPrimaryKey(key);
    }

    /***
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/3/14
     * @Description  根据example条件删除
     * @Param [example] 通用mapper的example对象
     * @Return int 影响的行数
     * @Exception //无
     * @since JDK 1.8       
     **/
    @Override
    public int deleteByExample(Object example) {
        //说明：根据主键字段进行删除，方法参数必须包含完整的主键属性
        return mapper.deleteByExample(example);
    }

    /***
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/3/14
     * @Description 更新所有字段
     * @Param [entity] 需要更新的实体对象
     * @Return int 影响的行数
     * @Exception //无
     * @since JDK 1.8
     **/
    @Override
    public int updateAll(T entity) {
        //说明：根据主键更新实体全部字段，null值会被更新
        return mapper.updateByPrimaryKey(entity);
    }

    /***
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/3/14
     * @Description 更新实体不为空的属性
     * @Param [entity] 需要更新的实体对象
     * @Return int 影响的行数
     * @Exception //无
     * @since JDK 1.8
     **/
    @Override
    public int updateNotNull(T entity) {
        //根据主键更新属性不为null的值
        return mapper.updateByPrimaryKeySelective(entity);
    }

    /***
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/3/14
     * @Description  根据example封装好的条件查询实体列表
     * @Param [example] 通用mapper的example对象
     * @Return java.util.List<T> 实体列表
     * @Exception //无
     * @since JDK 1.8
     **/
    @Override
    public List<T> selectByExample(Object example) {
        //说明：根据Example条件进行查询
        //重点：这个查询支持通过Example类指定查询列，通过selectProperties方法指定查询列
        return mapper.selectByExample(example);
    }

    /**
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/3/14
     * @Description 根据通用mapper封装好的exam对象查询记录数
     * @Param [example] 通用mapper的example对象
     * @Return int 影响行数
     * @Exception //无
     * @since JDK 1.8
     **/
    @Override
    public int selectCountByExample(Object example) {
        return mapper.selectCountByExample(example);
    }

    /***
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/3/14
     * @Description
     * @Param [entity] 需要删除的逻辑对象实体 注：必须实例一个对象传入，可以为空对象
     * @Return int 影响行数
     * @Exception 反射相关的异常，如访问未找到，非法访问等异常
     * @since JDK 1.8
     **/
    @Override
    public int deleteForLogic(T entity) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method method = entity.getClass().getMethod("setDeleted",Boolean.class);
        method.invoke(entity,true);
        return mapper.updateByPrimaryKeySelective(entity);
    }
    /***
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/3/16
     * @Description 根据通用mapper 的example 逻辑删除，只更新的非空字段
     * @Param [entity,example]更新的字段封装实体，通用mapper 的example条件
     * @Return int 删除成功标识 1标识删除成功 0标识删除失败
     * @Exception //TODO
     * @since JDK 1.8
     **/
    @Override
    public int deleteForLogicByExample(T entity,Object example) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        return mapper.updateByExampleSelective(entity, example);
    }
}